﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;

namespace AlgoritmosTA1
{
    class ArbolSintaxis
    {
        public string Info { get; set; } /* numero, *, /, +, mod, () */
        public ArbolSintaxis Izq { get; set; }
        public ArbolSintaxis Der { get; set; }
        public string CadCompleta { get; set; }

        public static Matriz m;

        public ArbolSintaxis()
        {
            Izq = null;
            Der = null;
            Info = "";
        }

        public ArbolSintaxis(string cad, string cadCompleta)
        {
            Izq = null;
            Der = null;
            Info = cad;
            CadCompleta = cadCompleta;
        }

        public ArbolSintaxis(string operador, ArbolSintaxis izq, ArbolSintaxis der, string cadCompleta)
        {
            Izq = izq;
            Der = der;
            Info = operador;
            CadCompleta = cadCompleta;
        }

        public static ArbolSintaxis ArmarArbol(string cad, string cad1)
        {
            string cadCompleta = cad1;

            if (cad[0].ToString().Equals(Constantes.Operacion)) cad = cad.Substring(1, cad.Length - 1);

            if (Constantes.CadenaValida(cad))
            {
                Constantes.NormalizarCadena(cad);

                if ((!Constantes.tieneOperador(cad)))
                {

                    return new ArbolSintaxis(Convert.ToString(cad), cadCompleta);
                }
                else
                {
                    if ((cad.IndexOf('(') == 0)) //encuentra parentesis
                    {
                        string[] op = Constantes.SepararCadena(cad);
                        if (op[1] == null)
                        {
                            return ArmarArbol(op[0], cadCompleta);
                        }
                        else
                        {
                            string operador = op[1];
                            ArbolSintaxis operando1 = ArmarArbol(op[0], op[0]);
                            ArbolSintaxis operando2 = ArmarArbol(op[2], op[2]);
                            return new ArbolSintaxis(operador, operando1, operando2, cadCompleta);
                        }

                    }
                    else
                    {

                        int i = cad.IndexOf('-');

                        if (i == -1)
                        {
                            i = cad.IndexOf('+');
                            if (i == -1)
                            {
                                i = cad.IndexOf('*');
                                if (i == -1)
                                {
                                    i = cad.IndexOf('/');
                                    if (i == -1)
                                    {
                                        i = cad.IndexOf('%');
                                    }
                                }
                            }
                        }

						string[] op = Constantes.SepararCadenaPosicion(cad, i);
                        string operador = op[1];
                        ArbolSintaxis operando1 = ArmarArbol(op[0], op[0]);
                        ArbolSintaxis operando2 = ArmarArbol(op[2], op[2]);


                        return new ArbolSintaxis(operador, operando1, operando2, cadCompleta); 
                    }
                }

            }

            return null;
        }

        public bool EsNodoOperador()
        {
            if ((Izq != null || Der != null) && (Constantes.EsOperador(Info)))
            {
                return true;
            }
            return false;
        }

		public bool EsHoja()
        {
            if ((Izq == null && Der == null))
            {
                return true;
            }
            return false;
        }


        public int Resolver()
        {
            if (!Constantes.EsOperador(Info))
            {
                if (Info.IndexOfAny(Constantes.Abecedario) != -1)
                {
                    ArbolSintaxis referencia = m.buscarCelda(Info);

                    if (referencia != null) return referencia.Resolver();
                    else return 0;
                }
                else if (Info.Equals("")) return 0;
                else return Convert.ToInt32(Info);
            }
            else
            {
                if ((Info != null) && (Izq != null) && (Der != null))
                {
                    if (Info.Equals(Constantes.Division))
                        return Izq.Resolver() / Der.Resolver();
                    else if (Info.Equals(Constantes.Modulo))
                        return Izq.Resolver() % Der.Resolver();
                    else if (Info.Equals(Constantes.Multiplicacion))
                        return Izq.Resolver() * Der.Resolver();
                    else if (Info.Equals(Constantes.Suma))
                        return Izq.Resolver() + Der.Resolver();
                    else if (Info.Equals(Constantes.Resta))
                        return Izq.Resolver() - Der.Resolver();
                    else
                    {
                        Debug.WriteLine("Hubo un error al parsear el operador. El operador no es válido.");
                        return 0;
                    }
                }
                else
                {
                    Debug.WriteLine("Hubo un error al parsear el operador. El operador no es válido.");
                    return 0;
                }
            }
        }

        

    }
}
